﻿// Type: AdvancedDataGridView.TreeGridView
// Assembly: ExpandableGridView, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 01AF7F03-14C8-403C-9988-D5C2B7E87D00
// Assembly location: C:\Users\lenovo\Desktop\TreeGridViewTest\TreeGridViewTest\lib\ExpandableGridView.dll

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Windows.Forms.VisualStyles;

namespace AdvancedDataGridView
{
    [DesignerCategory("code")]
    [Docking(DockingBehavior.Ask)]
    [ComplexBindingProperties]
    [Designer(typeof(ControlDesigner))]
    public class NTreeGridView : DataGridView
    {
        private bool _disposing = false;
        private bool _inExpandCollapse = false;
        internal bool _inExpandCollapseMouseCapture = false;
        private bool _showLines = true;
        private bool _virtualNodes = false;
        private bool _checkboxes = false;
        internal VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
        internal VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
        private int _indentWidth;
        private TreeGridNode _root;
        private TreeGridColumn _expandableColumn;
        internal ImageList _imageList;
        private Control hideScrollBarControl;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new object DataSource
        {
            get
            {
                return (object)null;
            }
            set
            {
                throw new NotSupportedException("The TreeGridView does not support databinding");
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Browsable(false)]
        public object DataMember
        {
            get
            {
                return (object)null;
            }
            set
            {
                throw new NotSupportedException("The TreeGridView does not support databinding");
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Browsable(false)]
        public new DataGridViewRowCollection Rows
        {
            get
            {
                return base.Rows;
            }
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new bool VirtualMode
        {
            get
            {
                return false;
            }
            set
            {
                throw new NotSupportedException("The TreeGridView does not support virtual mode");
            }
        }

        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        public new DataGridViewRow RowTemplate
        {
            get
            {
                return base.RowTemplate;
            }
            set
            {
                base.RowTemplate = value;
            }
        }

        [Category("Data")]
        [Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
        [Description("The collection of root nodes in the treelist.")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TreeGridNodeCollection Nodes
        {
            get
            {
                return this._root.Nodes;
            }
        }

        public TreeGridNode CurrentRow
        {
            get
            {
                return base.CurrentRow as TreeGridNode;
            }
        }

        [Description("Causes nodes to always show as expandable. Use the NodeExpanding event to add nodes.")]
        [DefaultValue(false)]
        public bool VirtualNodes
        {
            get
            {
                return this._virtualNodes;
            }
            set
            {
                this._virtualNodes = value;
            }
        }

        public TreeGridNode CurrentNode
        {
            get
            {
                return this.CurrentRow;
            }
        }

        [DefaultValue(true)]
        public bool ShowLines
        {
            get
            {
                return this._showLines;
            }
            set
            {
                if (value == this._showLines)
                    return;
                this._showLines = value;
                this.Invalidate();
            }
        }

        public ImageList ImageList
        {
            get
            {
                return this._imageList;
            }
            set
            {
                this._imageList = value;
            }
        }

        public bool CheckBoxes
        {
            get { return _checkboxes; }
            set { _checkboxes = value; }
        }

        public new int RowCount
        {
            get
            {
                return this.Nodes.Count;
            }
            set
            {
                for (int index = 0; index < value; ++index)
                    this.Nodes.Add(new TreeGridNode());
            }
        }

        public event ExpandingEventHandler NodeExpanding;

        public event ExpandedEventHandler NodeExpanded;

        public event CollapsingEventHandler NodeCollapsing;

        public event CollapsedEventHandler NodeCollapsed;

        public event CheckedEventHandler NodeChecked;

        public NTreeGridView()
        {           
            this.EditMode = DataGridViewEditMode.EditProgrammatically;
            this.RowTemplate = (DataGridViewRow)new TreeGridNode();
            this.AllowUserToAddRows = false;
            this.AllowUserToDeleteRows = false;
            this._root = new TreeGridNode(this);
            this._root.IsRoot = true;
            this.DoubleBuffered = true;
            base.Rows.CollectionChanged += (CollectionChangeEventHandler)((sender, e) => { });
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.Handled)
                return;
            Point currentCellAddress;
            int num;
            if (e.KeyCode == Keys.F2)
            {
                currentCellAddress = this.CurrentCellAddress;
                if (currentCellAddress.X > -1)
                {
                    currentCellAddress = this.CurrentCellAddress;
                    num = currentCellAddress.Y <= -1 ? 1 : 0;
                    goto label_5;
                }
            }
            num = 1;
        label_5:
            if (num == 0)
            {
                if (!this.CurrentCell.Displayed)
                {
                    NTreeGridView treeGridView = this;
                    currentCellAddress = this.CurrentCellAddress;
                    int y = currentCellAddress.Y;
                    treeGridView.FirstDisplayedScrollingRowIndex = y;
                }
                this.SelectionMode = DataGridViewSelectionMode.CellSelect;
                this.BeginEdit(true);
            }
            else if (e.KeyCode == Keys.Return && !this.IsCurrentCellInEditMode)
            {
                this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                this.CurrentCell.OwningRow.Selected = true;
            }
        }

        [Description("Returns the TreeGridNode for the given DataGridViewRow")]
        public TreeGridNode GetNodeForRow(DataGridViewRow row)
        {
            return row as TreeGridNode;
        }

        [Description("Returns the TreeGridNode for the given DataGridViewRow")]
        public TreeGridNode GetNodeForRow(int index)
        {
            return this.GetNodeForRow(base.Rows[index]);
        }

        protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
        {
            base.OnRowsAdded(e);
            for (int index = e.RowCount - 1; index >= 0; --index)
            {
                TreeGridNode treeGridNode = base.Rows[e.RowIndex + index] as TreeGridNode;
                if (treeGridNode != null)
                    treeGridNode.Sited();
            }
        }

        protected internal void UnSiteAll()
        {
            this.UnSiteNode(this._root);
        }

        protected internal virtual void UnSiteNode(TreeGridNode node)
        {
            if (!node.IsSited && !node.IsRoot)
                return;
            foreach (TreeGridNode node1 in node.Nodes)
                this.UnSiteNode(node1);
            if (!node.IsRoot)
            {
                base.Rows.Remove((DataGridViewRow)node);
                node.UnSited();
            }
        }

        protected internal virtual bool CollapseNode(TreeGridNode node)
        {
            if (!node.IsExpanded)
                return false;
            CollapsingEventArgs e = new CollapsingEventArgs(node);
            this.OnNodeCollapsing(e);
            if (!e.Cancel)
            {
                this.LockVerticalScrollBarUpdate(true);
                this.SuspendLayout();
                this._inExpandCollapse = true;
                node.IsExpanded = false;
                foreach (TreeGridNode node1 in node.Nodes)
                {
                    Debug.Assert(node1.RowIndex != -1, "Row is NOT in the grid.");
                    this.UnSiteNode(node1);
                }
                this.OnNodeCollapsed(new CollapsedEventArgs(node));
                this._inExpandCollapse = false;
                this.LockVerticalScrollBarUpdate(false);
                this.ResumeLayout(true);
                this.InvalidateCell(node.Cells[0]);
            }
            return !e.Cancel;
        }

        protected internal virtual void SiteNode(TreeGridNode node)
        {
            node._grid = this;
            TreeGridNode treeGridNode;
            if (node.Parent != null && !node.Parent.IsRoot)
            {
                Debug.Assert(node.Parent != null && node.Parent.IsExpanded);
                treeGridNode = node.Index <= 0 ? node.Parent : node.Parent.Nodes[node.Index - 1];
            }
            else
                treeGridNode = node.Index <= 0 ? (TreeGridNode)null : node.Parent.Nodes[node.Index - 1];
            int index;
            if (treeGridNode != null)
            {
                while (treeGridNode.Level >= node.Level && treeGridNode.RowIndex < base.Rows.Count - 1)
                {
                    treeGridNode = base.Rows[treeGridNode.RowIndex + 1] as TreeGridNode;
                    Debug.Assert(treeGridNode != null);
                }
                index = treeGridNode != node.Parent ? (treeGridNode.Level >= node.Level ? treeGridNode.RowIndex + 1 : treeGridNode.RowIndex) : treeGridNode.RowIndex + 1;
            }
            else
                index = 0;
            Debug.Assert(index != -1);
            this.SiteNode(node, index);
            Debug.Assert(node.IsSited);
            if (!node.IsExpanded)
                return;
            foreach (TreeGridNode node1 in node.Nodes)
                this.SiteNode(node1);
        }

        protected internal virtual void SiteNode(TreeGridNode node, int index)
        {
            if (index < base.Rows.Count)
                base.Rows.Insert(index, (DataGridViewRow)node);
            else
                base.Rows.Add((DataGridViewRow)node);
        }

        protected internal virtual bool ExpandNode(TreeGridNode node)
        {
            if (node.IsExpanded && !this._virtualNodes)
                return false;
            ExpandingEventArgs e = new ExpandingEventArgs(node);
            this.OnNodeExpanding(e);
            if (!e.Cancel)
            {
                this.LockVerticalScrollBarUpdate(true);
                this.SuspendLayout();
                this._inExpandCollapse = true;
                node.IsExpanded = true;
                foreach (TreeGridNode node1 in node.Nodes)
                {
                    Debug.Assert(node1.RowIndex == -1, "Row is already in the grid.");
                    this.SiteNode(node1);
                }
                this.OnNodeExpanded(new ExpandedEventArgs(node));
                this._inExpandCollapse = false;
                this.LockVerticalScrollBarUpdate(false);
                this.ResumeLayout(true);
                this.InvalidateCell(node.Cells[0]);
            }
            return !e.Cancel;
        }

        protected internal virtual void CheckedNode(TreeGridNode node)
        {
            this.OnNodeChecked(new CheckedEventArgs(node));
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            this._inExpandCollapseMouseCapture = false;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (this._inExpandCollapseMouseCapture)
                return;
            base.OnMouseMove(e);
        }

        protected virtual void OnNodeExpanding(ExpandingEventArgs e)
        {
            if (this.NodeExpanding == null)
                return;
            this.NodeExpanding((object)this, e);
        }

        protected virtual void OnNodeExpanded(ExpandedEventArgs e)
        {
            if (this.NodeExpanded == null)
                return;
            this.NodeExpanded((object)this, e);
        }

        protected virtual void OnNodeCollapsing(CollapsingEventArgs e)
        {
            if (this.NodeCollapsing == null)
                return;
            this.NodeCollapsing((object)this, e);
        }

        protected virtual void OnNodeCollapsed(CollapsedEventArgs e)
        {
            if (this.NodeCollapsed == null)
                return;
            this.NodeCollapsed((object)this, e);
        }

        protected virtual void OnNodeChecked(CheckedEventArgs e)
        {
            if (this.NodeChecked == null)
                return;
            this.NodeChecked((object)this, e);
        }

        protected override void Dispose(bool disposing)
        {
            this._disposing = true;
            base.Dispose(this.Disposing);
            this.UnSiteAll();
        }

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            this.hideScrollBarControl = new Control();
            this.hideScrollBarControl.Visible = false;
            this.hideScrollBarControl.Enabled = false;
            this.hideScrollBarControl.TabStop = false;
            this.Controls.Add(this.hideScrollBarControl);
        }

        protected override void OnRowEnter(DataGridViewCellEventArgs e)
        {
            base.OnRowEnter(e);
            if (this.SelectionMode != DataGridViewSelectionMode.CellSelect && (this.SelectionMode != DataGridViewSelectionMode.FullRowSelect || base.Rows[e.RowIndex].Selected))
                return;
            this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            base.Rows[e.RowIndex].Selected = true;
        }

        private void LockVerticalScrollBarUpdate(bool lockUpdate)
        {
            if (this._inExpandCollapse)
                return;
            if (lockUpdate)
                this.VerticalScrollBar.Parent = this.hideScrollBarControl;
            else
                this.VerticalScrollBar.Parent = (Control)this;
        }

        protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
        {
            if (typeof(TreeGridColumn).IsAssignableFrom(e.Column.GetType()) && this._expandableColumn == null)
                this._expandableColumn = (TreeGridColumn)e.Column;
            e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
            base.OnColumnAdded(e);
        }

        protected override void OnScroll(ScrollEventArgs e)
        {
            base.OnScroll(e);
            this.Invalidate();
        }

    }
}
